home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
boe.pres.k12.wv.us
/
boe.pres.k12.wv.us.zip
/
boe.pres.k12.wv.us
/
Utilities
/
Xerox Workcentre 5335
/
Windows Scan
/
32-bit_x86
/
Francais
/
cpsimage.cab
/
data
/
docio
/
xmldocutils.elf
< prev
next >
Wrap
Text File
|
2009-03-16
|
12KB
|
367 lines
/*
** $Id: xmldocutils.elf,v 1.6 2008/02/13 16:01:13 campanel Exp $
*/
#load "sys/xipxml.elf";
/* Used by the scripted method below */
/*
private
CLASS __Word {
METHOD compare( __Word left, __Word rite ) RETURNS( INTEGER result ) {
result = left.yb - rite.yb;
}
INTEGER x0;
INTEGER x1;
INTEGER x0_min;
INTEGER x0_max;
INTEGER x1_min;
INTEGER x1_max;
INTEGER xw;
INTEGER yb;
INTEGER fs;
XmlElement ele;
}
*/
/******************************************************************************/
/*
** This class provides the ability to coalesce words into sentences while in
** the XIPXML format.
*/
/* @New Creates a new instance of a XIPXML_COALESCEWORDS object. This object can be used to
progamatically access features of the language.
The xtol and ytol fields control the tolerence at which words will be joined. The
sw field controls the width of a space, also used to control when words will be
joined.
// EXAMPLE's
#load "docio/xmldocutils.elf";
STRING result = XIPXML_COALESCEWORDS.format( xipxml:input );
// or
XIPXML_COALESCEWORDS cw;
cw.xtol = 14; // more lose
cw.ytol = 6;
STRING result = cw.format( xipxml:input );
*/
/* @format Coalesces words into sentences based on settings in the class. */
CLASS XIPXML_COALESCEWORDS {
INTEGER ytol = 4; /* y direction tolerance */
INTEGER xtol = 12; /* x direction tolerance */
INTEGER sw = 16; /* size of space */
METHOD New () {}
METHOD format( STRING xipxml ) RETURNS( STRING result ) NATIVE "XIPXML_CoalesceWords@documentio";
/* This does the same as the native but is 20 times slower. */
/* Unless this algo needs to be customized, the native should
be used since this operation is done frequently. */
/*
METHOD format( STRING xipxml ) RETURNS( STRING result )
{
XmlDocumentBuilder db;
LIST lst;
INTEGER fnd, i, len;
STRING str, fs, fs_s;
__Word z, z_s;
XmlNode c;
// Will be moving nodes around, suppress whitespace to make it look nicer
db.useOptions( opts:XmlDocumentBuilder.XML_PARSE_NOBLANKS );
// Parse XML
XmlDocument d = db.parseString( doc:xipxml );
if( !d ) {
return;
}
// Build list of Glyphs nodes
XmlNode root = d.getDocumentElement();
if( root.getNodeName() != "Page" ) {
return;
}
for( c = root.getFirstChild(); c ; c = c.getNextSibling() ) {
if( c.getNodeName() == "Glyphs" ) {
z = new(__Word);
z.ele = c;
z.yb = z.ele.getAttribute( name:"yb" );
z.x0 = z.ele.getAttribute( name:"x0" );
z.xw = z.ele.getAttribute( name:"xw" );
z.fs = z.ele.getAttribute( name:"famStyle" );
z.x1 = z.x0 + z.xw;
z.x1_min = z.x1 + this.sw - this.xtol;
z.x1_max = z.x1 + this.sw + this.xtol;
z.x0_min = z.x0 - this.sw - this.xtol;
z.x0_max = z.x0 - this.sw + this.xtol;
lst.insert( obj:z );
}
}
// Sort list based on y position
__Word wrd;
lst.sort( comparator:wrd);
// Merge nodes based on position, removing merged nodes
for( fnd = 0; lst.length() != 0; fnd = 0 ) {
z = lst.ref( entry:0 );
len = lst.length();
for( i = 1; i < len; i++ ) {
z_s = lst.ref( entry:i );
if( (z_s.yb < (z.yb - this.ytol)) || (z_s.yb > (z.yb + this.ytol)) ) {
break;
}
if( z.fs != z_s.fs ) {
} else if( (z_s.x0 >= z.x1_min) && (z_s.x0 <= z.x1_max) ) {
str = z.ele.getAttribute( name:"str" ) + " " + z_s.ele.getAttribute( name:"str" );
z.ele.setAttribute( name:"str", value:str );
z.xw = z_s.x1 - z.x0;
z.x1 = z.x0 + z.xw;
z.x1_min = z.x1 + this.sw - this.xtol;
z.x1_max = z.x1 + this.sw + this.xtol;
str = z.xw;
z.ele.setAttribute( name:"xw", value:str );
lst.remove( entry:i );
root.removeChild( node:z_s.ele );
fnd = 1;
break;
} else if( (z_s.x1 >= z.x0_min) && (z_s.x1 <= z.x0_max) ) {
str = z_s.ele.getAttribute( name:"str" ) + " " + z.ele.getAttribute( name:"str" );
z.ele.setAttribute( name:"str", value:str );
z.x0 = z_s.x0;
z.x0_min = z.x0 - this.sw - this.xtol;
z.x0_max = z.x0 - this.sw + this.xtol;
str = z.x0;
z.ele.setAttribute( name:"x0", value:str );
z.xw = z.x1 - z_s.x0;
z.x1 = z.x0 + z.xw;
z.x1_min = z.x1 + this.sw - this.xtol;
z.x1_max = z.x1 + this.sw + this.xtol;
str = z.xw;
z.ele.setAttribute( name:"xw", value:str );
lst.remove( entry:i );
root.removeChild( node:z_s.ele );
fnd = 1;
break;
}
}
if( !fnd ) {
lst.remove( entry:0 );
}
}
// Save XML
result = d.dumpString( format:1 );
}
*/
}
/******************************************************************************/
/*
** This class provides the a simple holder for statistics on a font. It is
** commonly used when laying out text in an XIPXML text layer.
*/
/* @New Creates a new instance of a XIPXML_FONTSPEC object. This object is used
to provide statistics on a font when laying out text in an XIPXML text layer.
// EXAMPLE's
#load "docio/xmldocutils.elf";
XIPXML_FONTSPEC fs;
XIPXML_LAYER tl;
fs.cellWidth = 20; // Make the EM cell be 20px by 20px
fs.cellHeight = 20;
tl.addWord( str:"Hello World", x0:100, yb:100, font:fs );
*/
CLASS XIPXML_FONTSPEC {
INTEGER cellWidth = 24;
INTEGER cellHeight = 24;
INTEGER famStyle = 0;
INTEGER interLineSpacing = 8;
METHOD New() {}
}
/******************************************************************************/
/*
** This class provides simple methods for adding text to an XIPXML text layer.
*/
/* @New Creates a new instance of a XIPXML_LAYER object. This object is used
to add text to an XIPXML text layer.
// EXAMPLE's
#load "docio/xmldocutils.elf";
XIPXML_LAYER tl;
tl.loadLayer( img:img ); // Load the existing text layer from the XIPIMAGE
XIPXML_FONTSPEC fs;
fs.cellWidth = 20; // Make the EM cell be 20px by 20px
fs.cellHeight = 20;
tl.addWord( str:"Hello World", x0:100, yb:100, font:fs );
tl.saveLayer( img:img ); // Add or replace text layer on the XIPIMAGE
*/
/* @loadLayer Extract and parse a text layer from an XIPIMAGE object. */
/* @saveLayer Add or replace a text layer on an XIPIMAGE object. */
/* @addGlyph Adds a raw glyph with a string and a bounding box. */
/* @addWord Adds a simple word, or string, at the given (x0, yb) location. */
/* @addTextBox Adds a box of text defined by a width and a starting location (x0, yb). It
uses a very simple layout only suitable for Western languages. */
/* @addTextBoxByWords Adds a box of text defined by the number of words per line and
a starting location (x0, yb). It uses a very simple layout only
suitable for Western languages. */
CLASS XIPXML_LAYER {
XmlDocument xml; // private
METHOD New()
{
XmlDocumentBuilder db;
this.xml = db.parseString( doc:"<Page xw=\"0\" yh=\"0\"/>");
}
METHOD loadLayer( XIPIMAGE img )
{
XmlDocumentBuilder db;
INTEGER i, ltype, ttype;
STRING xipxml;
// Find the text layer
if( img ) {
for( i = 0; i < img.nlayers; i++ ) {
ltype = img.getMember( member:"layerType", num:i );
ttype = img.getMember( member:"textType", num:i );
if( (ltype == XIP_Text) && (ttype == XIP_XML_TEXT) ) {
xipxml = img.getMember( num:i, member:"text" );
break;
}
}
}
if( xipxml ) {
// Will be moving nodes around, suppress whitespace to make it look nicer
db.useOptions( opts:XmlDocumentBuilder.XML_PARSE_NOBLANKS );
// Parse XML
this.xml = db.parseString( doc:xipxml );
}
}
METHOD saveLayer( XIPIMAGE img )
{
// Save XML
STRING result = this.xml.dumpString( format:1 );
INTEGER i, ltype, ttype;
// Find the text layer
if( img ) {
for( i = 0; i < img.nlayers; i++ ) {
ltype = img.getMember( member:"layerType", num:i );
ttype = img.getMember( member:"textType", num:i );
if( (ltype == XIP_Text) && (ttype == XIP_XML_TEXT) ) {
xipxml = img.setMember( num:i, member:"text", value:result );
return;
}
}
// Add text layer
XIPLAYER layer = new( XIPLAYER, layerType:XIP_Text, visibility:FALSE );
img.addLayer( image:layer, ltype:XIP_Text, lindex:i );
img.setMember( num:i, member:"text", value:result );
img.setMember( num:i, member:"textType", value:XIP_XML_TEXT );
}
}
METHOD addGlyph( STRING str, INTEGER x0, INTEGER yb, INTEGER wd, INTEGER ht, INTEGER famStyle )
{
XmlNode root = this.xml.getDocumentElement();
XmlElement ele = this.xml.createElement( name:"Glyphs" );
STRING s;
ele.setAttribute( name:"str", value:str );
s = famStyle;
ele.setAttribute( name:"famStyle", value:s );
s = x0;
ele.setAttribute( name:"x0", value:s );
s = yb;
ele.setAttribute( name:"yb", value:s );
s = wd;
ele.setAttribute( name:"xw", value:s );
s = ht;
ele.setAttribute( name:"yh", value:s );
root.appendChild( node:ele );
}
METHOD addWord( STRING str, INTEGER x0, INTEGER yb, XIPXML_FONTSPEC font )
{
INTEGER wd;
wd = str.length() * font.cellWidth;
this.addGlyph( str:str, x0:x0, yb:yb, wd:wd, ht:font.cellHeight, famStyle:font.famStyle );
}
METHOD addTextBox( STRING str, INTEGER x0, INTEGER yb, INTEGER wd, XIPXML_FONTSPEC font )
{
INTEGER y = yb;
INTEGER x = x0;
INTEGER width;
LIST words = str.split( delims:" \t\n" );
foreach( words:s ) {
width = s.length() * font.cellWidth;
if( ((x + width) >= wd) && (x != x0) ) {
x = x0;
y += font.cellHeight + font.interLineSpacing;
}
this.addGlyph( str:s, x0:x, yb:y, wd:width, ht:font.cellHeight, famStyle:font.famStyle );
x += width + font.cellWidth;
}
}
METHOD addTextBoxByWords( STRING str, INTEGER x0, INTEGER yb, INTEGER wpl, XIPXML_FONTSPEC font )
{
INTEGER y = yb;
INTEGER x = x0;
INTEGER width;
INTEGER w = 0;
LIST words = str.split( delims:" \t\n" );
foreach( words:s ) {
width = s.length() * font.cellWidth;
this.addGlyph( str:s, x0:x, yb:y, wd:width, ht:font.cellHeight, famStyle:font.famStyle );
x += width + font.cellWidth;
w++;
if( w >= wpl ) {
x = x0;
y += font.cellHeight + font.interLineSpacing;
w = 0;
}
}
}
}